--- %%NOBANNER%% -->
/*-------------------<-- Start of Description -->--------------------\
| Generate multi-normial distrubtion; |
|--------------------<--- End of Description -->---------------------|
|--------------------------------------------------------------------|
|--------------<--- Start of Files or Arguments Needed -->-----------|
| Arguments required: |
| seed - the seed; default is the system time; |
| n - the dimension of the output array; |
| p - proportion table; |
| m - the total size of the multi-normial distribution; |
| var - the output var name or array names; |
| Other Arguments: |
| temp1 - internal temporary variable; |
| temp2 - internal temporary variable; |
| init - output the generated variates to an array; |
| if 1, create an array using the name of the "var"as |
| prefix; |
| otherwise, the input variable "var" is an array, just |
| use it to save the generated variates; |
|---------------<--- End of Files or Arguments Needed -->------------|
|--------------------------------------------------------------------|
|----------------<--- Start of Example and Usage -->-----------------|
| Example: |
| data one; |
| array _p(3) (0.25, 0.5, 0.25); |
| %_ranmult(seed=1, var=x, n=3, p=_p, m=5); |
| put x1-x3 _cdf1-_cdf2 seed; |
| do i=1 to 100000; |
| %_ranmult(seed=seed, var=x, m=5, n=3, p=_p, init=0); |
| output; |
| end; |
| run; proc print data=one(obs=200); run; |
| proc freq data=one; |
| tables x1-x3 / list missing; |
| run; |
| Usage: %_ranmult(seed=%sysfunc(datetime(), 15.), var=, n=, p=, m=, |
| temp1=_temp1, temp2=_temp2, init=1); |
\-------------------<--- End of Example and Usage -->---------------*/
%macro _ranmult(seed=%sysfunc(datetime(), 15.), var=, n=, p=, m=,
temp=_ranseed0_, temp1=_temp1, temp2=_temp2, init=1);
/*--------------------------------------------\
| Author: Duo Zhou; |
| Created: 3-23-2001 9:12pm; |
| Purpose: Random Multi-normial Generator; |
\--------------------------------------------*/
%if (%quote(&seed) eq) or (%quote(&var) eq) or (%quote(&n) eq) or (%quote(&m) eq) or (%quote(&p) eq) %then %do;
%if (%quote(&seed) eq) %then %do;
%put ==> Error: This is not a valid seed!;
%if (%length(&var)) %then %do; &var=.; %end;
%end;
%if (%quote(&var) eq) %then %do;
%put ==> Error: This function will need a valid array to save the generated random;
%put +++ variates!;
%if (%length(&var)) %then %do; &var=.; %end;
%end;
%if (%quote(&n) eq) %then %do;
%put ==> Error: I will save the generated random variates into the array "&var", so;
%put +++ please provide array dimension !;
%if (%length(&var)) %then %do; &var=.; %end;
%end;
%if (%quote(&p) eq) %then %do;
%put ==> Error: I need a valid proportion or proportion array!;
%if (%length(&var)) %then %do; &var=.; %end;
%end;
%if (%quote(&m) eq) %then %do;
%put ==> Error: I need a total size for multi-normal distribution!;
%if (%length(&var)) %then %do; &var=.; %end;
%end;
%goto finish;
%end;
%if (not %sysfunc(rxmatch(%sysfunc(rxparse(_|.|$a|$A|$w)),&seed))) %then %do;
drop &temp;
retain &temp &seed;
%let seed=&temp;
%end;
%if &init %then %do;
array &var(&n) &var.1 - &var.%left(&n);
%end;
do &temp1=1 to &n;
&var(&temp1)=0;
end;
do &temp1=1 to &m;
%_rantbl(seed=&seed, var=&temp2, n=&n, p=&p, init=&init);
&var(&temp2)=&var(&temp2)+1;
end;
%finish:
%mend _ranmult;